import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
import com.sun.org.apache.xml.internal.security.utils.Base64;


/**
 * @author xhoms
 * Class for basic string crypto funcitons using PBE and BASE64
 */
public class basicCrypto {
	private Cipher pbaCipher;  //  @jve:decl-index=0:
	private String encryptedPassword;  //  @jve:decl-index=0:
	private String decryptedPassword;  //  @jve:decl-index=0:
	private PBEKeySpec pbeKeySpec = new PBEKeySpec("basilio".toCharArray());  //  @jve:decl-index=0:
    private PBEParameterSpec pbeParamSpec;
    private SecretKeyFactory keyFac;
    private byte[] salt = {
        (byte)0xc7, (byte)0x73, (byte)0x21, (byte)0x8c,
        (byte)0x7e, (byte)0xc8, (byte)0xee, (byte)0x99
    };
    private int count = 20;
    private SecretKey pbeKey;

    /**
     * Initializes all class variables
     */
    public basicCrypto() {
		pbeParamSpec = new PBEParameterSpec(salt, count);
		try {
			keyFac = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
		} catch (NoSuchAlgorithmException e) {
			// doesn't make any sense to handle this exception as we're providing a static value
			e.printStackTrace();
		}
	    try {
			pbeKey = keyFac.generateSecret(pbeKeySpec);
		} catch (InvalidKeySpecException e) {
			// doesn't make any sense to handle this exception as we're providing a static value
			e.printStackTrace();
		}
		try {
			pbaCipher = Cipher.getInstance("PBEWithMD5AndDES");
		} catch (Exception e) {
			// doesn't make any sense to handle this exception as we're providing a static value
			e.printStackTrace();
		}
    }
    
	/**
	 * Returns Base64 PBE encrypted versions of the param String 
	 * @param password	The String to be encrypted
	 * @return			The Encription results 
	 */
	public String getCryptoPassword (String password) {
		try {
			pbaCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec);
		} catch (Exception e) {
			e.printStackTrace();
		}
		try {
			encryptedPassword = new String(Base64.encode(pbaCipher.doFinal(password.getBytes())));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return encryptedPassword;
	}
	
	/**
	 * Returns the plaint text based version of the Base64 PBE encrypted String
	 * @param password	The String to be decrypted
	 * @return			The Decryption result
	 * @throws Base64DecodingException 
	 * @throws BadPaddingException 
	 * @throws IllegalBlockSizeException 
	 */
	public String getDecryptedPassword (String password) throws IllegalBlockSizeException, BadPaddingException, Base64DecodingException {
		try {
			pbaCipher.init(Cipher.DECRYPT_MODE, pbeKey, pbeParamSpec);
		} catch (Exception e1) {
			// This should never hapen as were using static values
			e1.printStackTrace();
		}
		decryptedPassword = new String(pbaCipher.doFinal(Base64.decode(password.getBytes())));
		return decryptedPassword;
	}
}
